package services

import (
	"api_server/internal/models"
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	common "jihe.common"
	"jihe.common/oss"
	"jihe.common/protos/base_server"
	"jihe.common/protos/base_server/proto"
	"jihe.common/protos/calculate_server"
	calculate_server_proto "jihe.common/protos/calculate_server/proto"
	order_server_proto "jihe.common/protos/order_server/proto"
	"jihe.common/tool"
	"strings"
	"time"
)

//
//type baseService struct {
//	Config common.Config
//}

func uploadJson(dir, needId, orderId string) (string, error) {
	newUrl := fmt.Sprintf(`%s/%s/%s.json?%d`, common.Configer.Oss.Domain, dir, needId, time.Now().Unix())
	_, data, errs := tool.Request.Timeout(time.Second * 10).Get(newUrl).EndBytes()
	if len(errs) != 0 {
		return "", errs[0]
	}
	bucket, e := oss.GetClient().Bucket("jihe-file")
	if e != nil {
		return "", e
	}

	//如果是纹样，将纹样拆分以code为单位存起来，为生产物料使用
	if dir == "patterns" {
		patterns := make([]models.PatternInfo, 0)
		err := json.Unmarshal(data, &patterns)
		if err != nil {
			return "", err
		}
		vitemPatterns := make(map[string][]models.PatternInfo)
		for _, v := range patterns {
			vitemPatterns[v.Code] = append(vitemPatterns[v.Code], v)
		}
		for code, v := range vitemPatterns {
			path := fmt.Sprintf("patterns/%s/%s.json", orderId, code)
			vitemB, _ := json.Marshal(v)
			err := bucket.PutObject(path, bytes.NewReader(vitemB))
			if err != nil {
				common.Loger.Error("uploadJson split patterns err：%v", err)
			}
		}
	}

	path := fmt.Sprintf("%s/%d.json", time.Now().Format("2006-01-02"), tool.GetSnowflakeId())
	err := bucket.PutObject(path, bytes.NewReader(data))
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%s/%s", common.Configer.Oss.Domain, path), nil
}

func CopyOrderBaseInfo(needId, orderId string) (out order_server_proto.OrderBaseInfo, err error) {
	out.PatternUrl, err = uploadJson("patterns", needId, orderId)
	if err != nil {
		return
	}
	out.FabricUrl, err = uploadJson("fabrics", needId, orderId)
	if err != nil {
		return
	}
	out.TextureUrl, err = uploadJson("textures", needId, orderId)
	if err != nil {
		return
	}
	out.BackgroundColorUrl, err = uploadJson("backgrounds", needId, orderId)
	if err != nil {
		return
	}
	return
}

// 计算前的预处理
func PreCalculate(c *gin.Context, needId, from string) (err error) {
	//获取当前需求
	needDetail, err := base_server.BaseGetCustomerRegistrationDetail(c, &proto.BaseCustomerRegistration{Id: needId})
	if err != nil {
		err = fmt.Errorf("base_server.BaseGetCustomerRegistrationDetail" + err.Error())
		return
	}

	var (
		calculateFashionReq       *calculate_server_proto.CalculateFashionReq
		calculateCutpartQueuesReq *calculate_server_proto.CalculateCutpartQueues
		calculateFashionResult    *calculate_server_proto.CalculateFashionRes
		personTypeData            *proto.BaseFashionTypes
		fashionDetail             *proto.BaseGetFashionDetailRes
		afterCutparts             []*proto.BaseCutpart
		afterCutpartsMap          = make(map[string]string)
	)

	//如果已经算过此需求，直接跳过
	if needDetail.ObjUrl != "" {
		return
	}

	fashionDetail, err = base_server.BaseGetFashionDetail(c, &proto.BaseGetFashionDetailReq{Id: needDetail.FashionId})
	if err != nil {
		err = fmt.Errorf("base_server.BaseGetFashionDetail" + err.Error())
		return
	}
	//如果是客户端，要检测款式是否已上架
	if from == "client" {
		if fashionDetail.Fashion.Status != 2 {
			err = fmt.Errorf("errorno=1")
			return
		}
	}

	//计算款式
	calculateFashionReq = &calculate_server_proto.CalculateFashionReq{
		ObjUrl:  strings.Replace(fashionDetail.Fashion.ObjUrl, "jihe-file.oss-cn-beijing-internal.aliyuncs", "files.dizanz", -1),
		Kuoxing: fashionDetail.Fashion.AlgorithmParam.Wedo["kuoxing"],
		Type:    "2",
	}

	//如果设置腋下点，算一下平均值
	if len(fashionDetail.Fashion.AlgorithmParam.BaseFashionAlgorithmList) != 0 {
		calculateFashionReq.AlgorithmParam = tool.AveragePositon(fashionDetail.Fashion.AlgorithmParam.BaseFashionAlgorithmList)
	}

	personTypeData = GetOptions("person_type")
	for _, v := range personTypeData.BaseFashionTypeList {
		if v.Value == fashionDetail.Fashion.PersonType {
			calculateFashionReq.Tag = v.Tag
			break
		}
	}

	calculateFashionReq.BodyData = needDetail.BodyData
	calculateFashionResult, err = calculate_server.CalculateFashion(c, calculateFashionReq)
	if err != nil {
		err = fmt.Errorf("calculate_server.CalculateFashion" + err.Error())
		return
	}

	_, err = base_server.BaseUpdateCustomerRegistration(c, &proto.BaseCustomerRegistration{
		Id:     needId,
		ObjUrl: calculateFashionResult.Url,
	})
	if err != nil {
		err = fmt.Errorf("base_server.BaseUpdateCustomerRegistration" + err.Error())
		return
	}

	//将计算之后的款式分割
	afterCutparts, err = tool.SplitObj(calculateFashionResult.Url)
	if err != nil {
		err = fmt.Errorf("tool.SplitObj" + err.Error())
		return
	}

	for _, v := range afterCutparts {
		afterCutpartsMap[v.Code] = v.ObjUrl
	}

	craft := models.FashionCraft{}
	superCraftUrl := fmt.Sprintf("%s/%s_crafts/%s.json?%d", common.Configer.Oss.Domain, common.Configer.Runmode, needDetail.FashionId, tool.GetSnowflakeId())
	tool.GetRequest().Get(superCraftUrl).Timeout(time.Second * 10).EndStruct(&craft)

	//需要计算的裁片写入计算服务
	calculateCutpartQueuesReq = &calculate_server_proto.CalculateCutpartQueues{}
	for _, v := range fashionDetail.BaseCutpartList {
		straightLineIdxArr := []string{}
		for _, item := range craft.SlopeList {
			if item.Code == v.Code {
				for _, indexs := range item.Indexs {
					straightLineIdxArr = append(straightLineIdxArr, fmt.Sprintf("%s:1", tool.JoinIntArr(indexs, ",")))
				}
			}
		}
		gapIdxArr := []string{}
		for _, item := range craft.GapList {
			if item.Code == v.Code {
				for _, indexs := range item.Indexs {
					gapIdxArr = append(gapIdxArr, fmt.Sprintf("%s:%s", tool.JoinIntArr(indexs, ","), item.Width))
				}
			}
		}
		interiorInfoByte, e := json.Marshal(craft.InteriorInfo[v.Code])
		interiorInfoByteStr := ""
		if len(interiorInfoByte) != 0 && e != nil {
			interiorInfoByteStr = string(interiorInfoByte)
		}
		calculateCutpartQueuesReq.List = append(calculateCutpartQueuesReq.List, &calculate_server_proto.CalculateCutpartQueue{
			CutpartId:       v.Id,
			NeedId:          needId,
			ObjUrl:          afterCutpartsMap[v.Code], //计算款式之后分割出的obj
			Code:            v.Code,
			UvWidth:         fashionDetail.Fashion.AlgorithmParam.UvWidth,
			BeforObjUrl:     v.ObjUrl,
			DxfUrl:          fashionDetail.Fashion.DxfUrl,
			StraightLineIdx: strings.Join(straightLineIdxArr, ";"),
			GapIdx:          strings.Join(gapIdxArr, ";"),
			DxfInfoUrl:      fashionDetail.Fashion.CutpartBorderPoint,
			InteriorInfo:    interiorInfoByteStr,
		})
	}
	_, err = calculate_server.CalculateCreateCutpartQueue(c, calculateCutpartQueuesReq)
	if err != nil {
		err = fmt.Errorf("calculate_server.CalculateCreateCutpartQueue" + err.Error())
		return
	}
	return nil
}
